#include "util.h"
#include <chrono>
#include <vector>
#include <execinfo.h>
#include <cstring>
#include <sstream>
#include "log.h"
#include "fiber.h"
#include <iostream>
namespace sylar
{
    static uint64_t s_start_time = 0; // 程序启动时间（毫秒）
    sylar::Logger::ptr g_logger = SYLAR_LOG_NAME("system");
    void InitUtil()
    {
        std::cout << "InitUtil\n";
        if (s_start_time == 0)
        {
            auto now = std::chrono::system_clock::now();
            s_start_time = std::chrono::duration_cast<std::chrono::milliseconds>(
                               now.time_since_epoch())
                               .count();
        }
    }
    uint64_t GetElapse()
    {
        auto now = std::chrono::system_clock::now();
        auto now_ms = std::chrono::duration_cast<std::chrono::milliseconds>(
                          now.time_since_epoch())
                          .count();
        return now_ms - s_start_time;
    }

    uint64_t GetTime()
    {
        return std::chrono::system_clock::to_time_t(
            std::chrono::system_clock::now());
    }

    pid_t GetThreadId()
    {
        return syscall(SYS_gettid);
    }

    uint64_t GetFiberId()
    {
        return sylar::Fiber::GetFiberId();
    }

    //        #include <execinfo.h>

    //    int backtrace(void *buffer[.size], int size);

    //    char **backtrace_symbols(void *const buffer[.size], int size);
    //    void backtrace_symbols_fd(void *const buffer[.size], int size, int fd);
    void BackTrace(std::vector<std::string> &bt, int size, int skip )
    {
        void **back_array = (void **)malloc(size * sizeof(void *));
        if (back_array == nullptr)
        {
            SYLAR_LOG_ERROR(SYLAR_ERROR_LOGGER()) << "sylar::BackTrace(): error : back_array ==nullptr ";
            return;
        }

        size_t s = ::backtrace(back_array, size);

        char **strings = backtrace_symbols(back_array, s);
        if (strings == nullptr)
        {
            SYLAR_LOG_ERROR(g_logger) << " sylar::BackTrace() backtrace_symbols error\n";
            free(back_array);
            return;
        }
        for (size_t i = skip; i < s; ++i)
        {
            bt.emplace_back(std::string(strings[i]));
        }
        free(strings);
        free(back_array);
    }

    std::string BackTraceToString(int size, int skip, const std::string &prefix)
    {
        std::vector<std::string> bt;
        BackTrace(bt, size, skip);
        std::stringstream ss;
        for (size_t i = 0; i < bt.size(); ++i)
        {
            ss << prefix << bt[i] << std::endl;
        }
        return ss.str();
    }
}